package thread;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: xiaotutu
 * Date: 2025-02-20
 * Time: 17:34
 */

class MyBlockingQueue {
    // 使用一个 String 类型的数组来保存元素. 假设这里只存 String.
    private String[] items = new String[1000];
    // 指向队列的头部
    volatile private int head = 0;
    // 指向队列的尾部的下一个元素. 总的来说, 队列中有效元素的范围 [head, tail)
    // 当 head 和 tail 相等(重合), 相当于空的队列.
    volatile private int tail = 0;
    // 使用 size 来表示元素个数.
    volatile private int size = 0;

    private Object locker = new Object();

    //入队列
    public void put(String elem) throws InterruptedException {
        synchronized (locker) {
            while (size >= items.length) {
                // 队列满了 暂时不能入队列
                //return;
                locker.wait();
            }

            items[tail] = elem;
            tail++;
            if (tail >= items.length) {
                tail = 0;
            }
            size++;
            locker.notify();
        }
    }

    //出队列
    public String take() throws InterruptedException {
        synchronized (locker) {
            while (size == 0) {
                // 队列空了 暂时不能出队列
                // return null;
                locker.wait();
            }
            String elem = items[head];
            head++;
            if (head >= items.length) {
                head = 0;
            }
            size--;
            locker.notify();
            return elem;
        }
    }
}

public class Demo20 {
    public static void main(String[] args) {
        // 交易场所
        MyBlockingQueue queue = new MyBlockingQueue();

        // 创建两个线程 表示生产者和消费者
        Thread t1 = new Thread(() -> {
            int count = 0;
            while (true) {
                try {
                    queue.put(count + "");
                    System.out.println("生产元素: " + count);
                    count++;

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread t2 = new Thread(() -> {
            while (true) {
                try {
                    String ret = queue.take();
                    Thread.sleep(1000);
                    System.out.println("消费元素: " + ret);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        t1.start();;
        t2.start();
    }
}
